//
//  AppDelegate.cpp
//  OpenGLDemo
//
//  Created by 石超军 on 2018/7/6.
//  Copyright © 2018年 石超军. All rights reserved.
//
#include <OpenGL/gl3.h>
#include "AppDelegate.h"

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include "CVertex.h"
#include "CShader.h"
#include "CTexture2D.h"
#include "CMesh.h"
#include "CModel.h"



#define VEROBJ_ROOT "/Users/cnscj/XcodeWorkspace/SLearnOpenGL/OpenGLDemo/VertexObject/"
#define VERTEXT_ROOT "/Users/cnscj/XcodeWorkspace/SLearnOpenGL/OpenGLDemo/VertexShader/"
#define FRAGMENT_ROOT "/Users/cnscj/XcodeWorkspace/SLearnOpenGL/OpenGLDemo/FragmentShader/"
#define TEXTURE_ROOT "/Users/cnscj/XcodeWorkspace/SLearnOpenGL/OpenGLDemo/Texture/"
#define MODEL_ROOT "/Users/cnscj/XcodeWorkspace/SLearnOpenGL/OpenGLDemo/Models/"

#include "VertexObject/VertexCommon.h"
void AppDelegate::OnInit()
{
    
}
void AppDelegate::OnInput()
{
    GLSApplication::OnInput();
    
    if (glfwGetKey(GetWindowHandle(), GLFW_KEY_W) == GLFW_PRESS)
        m_camera.ProcessKeyboard(FORWARD, 0.016f);
    if (glfwGetKey(GetWindowHandle(), GLFW_KEY_S) == GLFW_PRESS)
        m_camera.ProcessKeyboard(BACKWARD, 0.016f);
    if (glfwGetKey(GetWindowHandle(), GLFW_KEY_A) == GLFW_PRESS)
        m_camera.ProcessKeyboard(LEFT, 0.016f);
    if (glfwGetKey(GetWindowHandle(), GLFW_KEY_D) == GLFW_PRESS)
        m_camera.ProcessKeyboard(RIGHT, 0.016f);
    if (glfwGetKey(GetWindowHandle(), GLFW_KEY_R) == GLFW_PRESS)
        m_camera.ProcessKeyboard(UP, 0.016f);
    if (glfwGetKey(GetWindowHandle(), GLFW_KEY_F) == GLFW_PRESS)
        m_camera.ProcessKeyboard(DOWN, 0.016f);
    if (glfwGetKey(GetWindowHandle(), GLFW_KEY_Q) == GLFW_PRESS)
        m_camera.ProcessMouseMovement(-20.0f, 0);
    if (glfwGetKey(GetWindowHandle(), GLFW_KEY_E) == GLFW_PRESS)
        m_camera.ProcessMouseMovement(20.0f, 0);
}
void AppDelegate::OnRender()
{
    glEnable(GL_DEPTH_TEST);
    /* Render here */
    //glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    _ModelTest1();
}

void AppDelegate::_ModelTest1()
{
    static struct SOnce
    {
        CShader ourShader;
        CModel ourModel;
        SOnce()
        :ourShader(VERTEXT_ROOT"modelTest1.vs", FRAGMENT_ROOT"modelTest1.fs")
        ,ourModel(MODEL_ROOT"nanosuit/nanosuit.obj")
        {
            
        }
    }obj;

    obj.ourShader.Use();
    // view/projection transformations
    glm::mat4 model(1.0f);
    model = glm::translate(model, glm::vec3(0.0f, -1.75f, 0.0f));   // translate it down so it's at the center of the scene
    model = glm::scale(model, glm::vec3(0.2f, 0.2f, 0.2f));         // it's a bit too big for our scene, so scale it down
    glm::mat4 projection = glm::perspective(glm::radians(m_camera.Zoom), (float)GetWidth() / (float)GetHeight(), 0.1f, 100.0f);
    glm::mat4 view = m_camera.GetViewMatrix();
    obj.ourShader.SetMat4("model", model);
    obj.ourShader.SetMat4("projection", projection);
    obj.ourShader.SetMat4("view", view);
    
    obj.ourModel.Draw(obj.ourShader);
}

void AppDelegate::_MulLightTest2()
{
    CVertex lighting(&MODEL_CUBE_PTN);
    CVertex lamp(&MODEL_CUBE);
    CTexture2D diffuseMap(TEXTURE_ROOT"container2.png");
    CTexture2D specularMap(TEXTURE_ROOT"lighting_maps_specular_color.png");
    CShader lightingShader(VERTEXT_ROOT"mullightTest1.vs",FRAGMENT_ROOT"mullightTest2.fs");
    CShader lampShader(VERTEXT_ROOT"mullightTest1-lamp.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    unsigned int i = 0;
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    
    model = glm::mat4(1.0f);
    view = m_camera.GetViewMatrix();
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    
     glm::vec3 pointLightPositions[] =
    {
        glm::vec3(cos((float)glfwGetTime()+ 1*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 1*3.14*2/3)+ 0.1*(float)glfwGetTime())), sin((float)glfwGetTime()+ 1*3.14*2/3)),
        glm::vec3(cos((float)glfwGetTime()+ 2*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 2*3.14*2/3)+ 0.1*(float)glfwGetTime())), sin((float)glfwGetTime()+ 2*3.14*2/3)),
        glm::vec3(cos((float)glfwGetTime()+ 3*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 3*3.14*2/3)+ 0.1*(float)glfwGetTime())), sin((float)glfwGetTime()+ 3*3.14*2/3))
    };
    
    lightingShader.Use();
    diffuseMap.Active(GL_TEXTURE0);
    specularMap.Active(GL_TEXTURE1);
    
    lightingShader.SetMat4("projection", projection);
    lightingShader.SetMat4("view", view);
    
    // be sure to activate shader when setting uniforms/drawing objects
    lightingShader.SetVec3("viewPos", m_camera.Position);
    
    lightingShader.SetInt("material.diffuse", 0);
    lightingShader.SetInt("material.specular", 1);
    lightingShader.SetFloat("material.shininess", 32.0f);
    /*
     Here we set all the uniforms for the 5/6 types of lights we have. We have to set them manually and index
     the proper PointLight struct in the array to set each uniform variable. This can be done more code-friendly
     by defining light types as classes and set their values in there, or by using a more efficient uniform approach
     by using 'Uniform buffer objects', but that is something we'll discuss in the 'Advanced GLSL' tutorial.
     */
    // directional light
    lightingShader.SetVec3("dirLight.direction", -0.2f, -1.0f, -0.3f);
    lightingShader.SetVec3("dirLight.ambient", 0.05f, 0.05f, 0.05f);
    lightingShader.SetVec3("dirLight.diffuse", 0.4f, 0.4f, 0.4f);
    lightingShader.SetVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
    // point light 1
    lightingShader.SetVec3("pointLights[0].position", pointLightPositions[0]);
    lightingShader.SetVec3("pointLights[0].ambient", 0.05f, 0.05f, 0.05f);
    lightingShader.SetVec3("pointLights[0].diffuse", 0.8f, 0.8f, 0.8f);
    lightingShader.SetVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f);
    lightingShader.SetFloat("pointLights[0].constant", 1.0f);
    lightingShader.SetFloat("pointLights[0].linear", 0.09f);
    lightingShader.SetFloat("pointLights[0].quadratic", 0.032f);
    // point light 2
    lightingShader.SetVec3("pointLights[1].position", pointLightPositions[1]);
    lightingShader.SetVec3("pointLights[1].ambient", 0.05f, 0.05f, 0.05f);
    lightingShader.SetVec3("pointLights[1].diffuse", 0.8f, 0.8f, 0.8f);
    lightingShader.SetVec3("pointLights[1].specular", 1.0f, 1.0f, 1.0f);
    lightingShader.SetFloat("pointLights[1].constant", 1.0f);
    lightingShader.SetFloat("pointLights[1].linear", 0.09f);
    lightingShader.SetFloat("pointLights[1].quadratic", 0.032f);
    // point light 3
    lightingShader.SetVec3("pointLights[2].position", pointLightPositions[2]);
    lightingShader.SetVec3("pointLights[2].ambient", 0.05f, 0.05f, 0.05f);
    lightingShader.SetVec3("pointLights[2].diffuse", 0.8f, 0.8f, 0.8f);
    lightingShader.SetVec3("pointLights[2].specular", 1.0f, 1.0f, 1.0f);
    lightingShader.SetFloat("pointLights[2].constant", 1.0f);
    lightingShader.SetFloat("pointLights[2].linear", 0.09f);
    lightingShader.SetFloat("pointLights[2].quadratic", 0.032f);

    // spotLight
    lightingShader.SetVec3("spotLight.position", m_camera.Position);
    lightingShader.SetVec3("spotLight.direction", m_camera.Front);
    lightingShader.SetVec3("spotLight.ambient", 0.0f, 0.0f, 0.0f);
    lightingShader.SetVec3("spotLight.diffuse", 1.0f, 1.0f, 1.0f);
    lightingShader.SetVec3("spotLight.specular", 1.0f, 1.0f, 1.0f);
    lightingShader.SetFloat("spotLight.constant", 1.0f);
    lightingShader.SetFloat("spotLight.linear", 0.09f);
    lightingShader.SetFloat("spotLight.quadratic", 0.032f);
    lightingShader.SetFloat("spotLight.cutOff", glm::cos(glm::radians(12.5f)));
    lightingShader.SetFloat("spotLight.outerCutOff", glm::cos(glm::radians(15.0f)));
    
    // also draw the lamp object(s)
    lampShader.Use();       //每次都要设置一次
    lampShader.SetMat4("projection", projection);
    lampShader.SetMat4("view", view);
    
    lightingShader.Use();//每次都要设置一次
    lighting.Bind();
    
    {
        // calculate the model matrix for each object and pass it to shader before drawing
        model = glm::mat4(1.0f);
        model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(0.5f, 1.0f, 0.0f));
        lightingShader.SetMat4("model", model);
        
        glDrawArrays(GL_TRIANGLES, 0, 36);
    }
    
    
    lamp.Bind();
    lampShader.Use();
    for(i = 0; i < 3; i++)
    {
        model = glm::mat4(1.0f);
        model = glm::translate(model, pointLightPositions[i]);
        model = glm::scale(model, glm::vec3(0.2f)); // Make it a smaller cube
        lampShader.SetMat4("model", model);
        
        glDrawArrays(GL_TRIANGLES, 0, 36);
    }
}

void AppDelegate::_MulLightTest1()
{
    CVertex lighting(&MODEL_CUBE_PTN);
    CVertex lamp(&MODEL_CUBE);
    CTexture2D diffuseMap(TEXTURE_ROOT"container2.png");
    CTexture2D specularMap(TEXTURE_ROOT"lighting_maps_specular_color.png");
    CShader lightingShader(VERTEXT_ROOT"mullightTest1.vs",FRAGMENT_ROOT"mullightTest1.fs");
    CShader lampShader(VERTEXT_ROOT"mullightTest1-lamp.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    //glm::vec3 lightPos = glm::vec3(-0.2f, -1.0f, -0.3f);
    //lightPos = glm::vec3(3*cos((float)glfwGetTime()+ 1*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 1*3.14*2/3)+ 0.05*(float)glfwGetTime())) , 3*sin((float)glfwGetTime()+ 1*3.14*2/3));
    
    glm::vec3 cubePositions[] = {
        glm::vec3( 0.0f,  0.0f,  0.0f),
        glm::vec3( 2.0f,  5.0f, -15.0f),
        glm::vec3(-1.5f, -2.2f, -2.5f),
        glm::vec3(-3.8f, -2.0f, -12.3f),
        glm::vec3( 2.4f, -0.4f, -3.5f),
        glm::vec3(-1.7f,  3.0f, -7.5f),
        glm::vec3( 1.3f, -2.0f, -2.5f),
        glm::vec3( 1.5f,  2.0f, -2.5f),
        glm::vec3( 1.5f,  0.2f, -1.5f),
        glm::vec3(-1.3f,  1.0f, -1.5f)
    };
    
    // positions of the point lights
    glm::vec3 pointLightPositions[] = {
        glm::vec3( 0.7f,  0.2f,  2.0f),
        glm::vec3( 2.3f, -3.3f, -4.0f),
        glm::vec3(-4.0f,  2.0f, -12.0f),
        glm::vec3( 0.0f,  0.0f, -3.0f)
    };
    
    unsigned int i = 0;
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    
    model = glm::mat4(1.0f);
    view = m_camera.GetViewMatrix();
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    
    lightingShader.Use();
    diffuseMap.Active(GL_TEXTURE0);
    specularMap.Active(GL_TEXTURE1);
    lightingShader.SetMat4("projection", projection);
    lightingShader.SetMat4("view", view);
    
    // be sure to activate shader when setting uniforms/drawing objects
    lightingShader.SetVec3("viewPos", m_camera.Position);
    
    lightingShader.SetInt("material.diffuse", 0);
    lightingShader.SetInt("material.specular", 1);
    lightingShader.SetFloat("material.shininess", 32.0f);
    /*
     Here we set all the uniforms for the 5/6 types of lights we have. We have to set them manually and index
     the proper PointLight struct in the array to set each uniform variable. This can be done more code-friendly
     by defining light types as classes and set their values in there, or by using a more efficient uniform approach
     by using 'Uniform buffer objects', but that is something we'll discuss in the 'Advanced GLSL' tutorial.
     */
    // directional light
    lightingShader.SetVec3("dirLight.direction", -0.2f, -1.0f, -0.3f);
    lightingShader.SetVec3("dirLight.ambient", 0.05f, 0.05f, 0.05f);
    lightingShader.SetVec3("dirLight.diffuse", 0.4f, 0.4f, 0.4f);
    lightingShader.SetVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
    // point light 1
    lightingShader.SetVec3("pointLights[0].position", pointLightPositions[0]);
    lightingShader.SetVec3("pointLights[0].ambient", 0.05f, 0.05f, 0.05f);
    lightingShader.SetVec3("pointLights[0].diffuse", 0.8f, 0.8f, 0.8f);
    lightingShader.SetVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f);
    lightingShader.SetFloat("pointLights[0].constant", 1.0f);
    lightingShader.SetFloat("pointLights[0].linear", 0.09f);
    lightingShader.SetFloat("pointLights[0].quadratic", 0.032f);
    // point light 2
    lightingShader.SetVec3("pointLights[1].position", pointLightPositions[1]);
    lightingShader.SetVec3("pointLights[1].ambient", 0.05f, 0.05f, 0.05f);
    lightingShader.SetVec3("pointLights[1].diffuse", 0.8f, 0.8f, 0.8f);
    lightingShader.SetVec3("pointLights[1].specular", 1.0f, 1.0f, 1.0f);
    lightingShader.SetFloat("pointLights[1].constant", 1.0f);
    lightingShader.SetFloat("pointLights[1].linear", 0.09f);
    lightingShader.SetFloat("pointLights[1].quadratic", 0.032f);
    // point light 3
    lightingShader.SetVec3("pointLights[2].position", pointLightPositions[2]);
    lightingShader.SetVec3("pointLights[2].ambient", 0.05f, 0.05f, 0.05f);
    lightingShader.SetVec3("pointLights[2].diffuse", 0.8f, 0.8f, 0.8f);
    lightingShader.SetVec3("pointLights[2].specular", 1.0f, 1.0f, 1.0f);
    lightingShader.SetFloat("pointLights[2].constant", 1.0f);
    lightingShader.SetFloat("pointLights[2].linear", 0.09f);
    lightingShader.SetFloat("pointLights[2].quadratic", 0.032f);
    // point light 4
    lightingShader.SetVec3("pointLights[3].position", pointLightPositions[3]);
    lightingShader.SetVec3("pointLights[3].ambient", 0.05f, 0.05f, 0.05f);
    lightingShader.SetVec3("pointLights[3].diffuse", 0.8f, 0.8f, 0.8f);
    lightingShader.SetVec3("pointLights[3].specular", 1.0f, 1.0f, 1.0f);
    lightingShader.SetFloat("pointLights[3].constant", 1.0f);
    lightingShader.SetFloat("pointLights[3].linear", 0.09f);
    lightingShader.SetFloat("pointLights[3].quadratic", 0.032f);
    // spotLight
    lightingShader.SetVec3("spotLight.position", m_camera.Position);
    lightingShader.SetVec3("spotLight.direction", m_camera.Front);
    lightingShader.SetVec3("spotLight.ambient", 0.0f, 0.0f, 0.0f);
    lightingShader.SetVec3("spotLight.diffuse", 1.0f, 1.0f, 1.0f);
    lightingShader.SetVec3("spotLight.specular", 1.0f, 1.0f, 1.0f);
    lightingShader.SetFloat("spotLight.constant", 1.0f);
    lightingShader.SetFloat("spotLight.linear", 0.09f);
    lightingShader.SetFloat("spotLight.quadratic", 0.032f);
    lightingShader.SetFloat("spotLight.cutOff", glm::cos(glm::radians(12.5f)));
    lightingShader.SetFloat("spotLight.outerCutOff", glm::cos(glm::radians(15.0f)));
    
    // also draw the lamp object(s)
    lampShader.Use();       //每次都要设置一次
    lampShader.SetMat4("projection", projection);
    lampShader.SetMat4("view", view);
    
    lightingShader.Use();//每次都要设置一次
    lighting.Bind();
    for(i = 0; i < 10; i++)
    {
        // calculate the model matrix for each object and pass it to shader before drawing
        model = glm::mat4(1.0f);
        model = glm::translate(model, cubePositions[i]);
        float angle = 20.0f * i;
        model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
        lightingShader.SetMat4("model", model);
        
        glDrawArrays(GL_TRIANGLES, 0, 36);
    }
    
    
    lamp.Bind();
    lampShader.Use();
    for(i = 0; i < 4; i++)
    {
        model = glm::mat4(1.0f);
        model = glm::translate(model, pointLightPositions[i]);
        model = glm::scale(model, glm::vec3(0.2f)); // Make it a smaller cube
        lampShader.SetMat4("model", model);
        
        glDrawArrays(GL_TRIANGLES, 0, 36);
    }
}

void AppDelegate::_LightCasterTest3()
{

    CVertex lighting(&MODEL_CUBE_PTN);
    CVertex lamp1(&MODEL_CUBE);
    CTexture2D diffuseMap(TEXTURE_ROOT"container2.png");
    CTexture2D specularMap(TEXTURE_ROOT"lighting_maps_specular_color.png");
    CShader lightingShader(VERTEXT_ROOT"lightcasterTest1.vs",FRAGMENT_ROOT"lightcasterTest3-1.fs");
    CShader lampShader(VERTEXT_ROOT"colorTest1-1.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::vec3 lightPos = glm::vec3(-0.2f, -1.0f, -0.3f);
    lightPos = glm::vec3(3*cos((float)glfwGetTime()+ 1*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 1*3.14*2/3)+ 0.05*(float)glfwGetTime())) , 3*sin((float)glfwGetTime()+ 1*3.14*2/3));
    
    glm::vec3 cubePositions[] = {
        glm::vec3( 0.0f,  0.0f,  0.0f),
        glm::vec3( 2.0f,  5.0f, -15.0f),
        glm::vec3(-1.5f, -2.2f, -2.5f),
        glm::vec3(-3.8f, -2.0f, -12.3f),
        glm::vec3( 2.4f, -0.4f, -3.5f),
        glm::vec3(-1.7f,  3.0f, -7.5f),
        glm::vec3( 1.3f, -2.0f, -2.5f),
        glm::vec3( 1.5f,  2.0f, -2.5f),
        glm::vec3( 1.5f,  0.2f, -1.5f),
        glm::vec3(-1.3f,  1.0f, -1.5f)
    };
    
    glm::mat4 world(1.0f);
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    for(unsigned int i = 0; i < 10; i++)
    {
        lightingShader.Use();
        diffuseMap.Active(GL_TEXTURE0);
        specularMap.Active(GL_TEXTURE1);
        model = glm::mat4(1.0f);
        model = glm::translate(model, cubePositions[i]);
        float angle = 20.0f * i;
        model = glm::rotate(model, (float)glfwGetTime() * glm::radians(angle), glm::vec3(cos((float)glfwGetTime()), 1.0f, sin((float)glfwGetTime())));
        view = m_camera.GetViewMatrix();
        projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
        lightingShader.SetMat4("model", model);
        lightingShader.SetMat4("view", view);
        lightingShader.SetMat4("projection", projection);
        lightingShader.SetVec3("viewPos", m_camera.Position);
        
        //材质
        lightingShader.SetInt("material.diffuse", 0);
        lightingShader.SetInt("material.specular", 1);
        lightingShader.SetFloat("material.shininess", 32.0f);
        
        lightingShader.SetVec4("light.lightVector", lightPos.x, lightPos.y, lightPos.z,0.0f);
        lightingShader.SetVec3("light.ambient", 0.2f, 0.2f, 0.2f);
        lightingShader.SetVec3("light.diffuse", 0.5f, 0.5f, 0.5f);
        lightingShader.SetVec3("light.specular", 1.0f, 1.0f, 1.0f);
        
        lightingShader.SetFloat("light.constant",  1.0f);
        lightingShader.SetFloat("light.linear",    0.09f);
        lightingShader.SetFloat("light.quadratic", 0.032f);
        
        lightingShader.SetVec3("light.position",  m_camera.Position);
        lightingShader.SetVec3("light.direction", m_camera.Front);
        lightingShader.SetFloat("light.cutOff",   glm::cos(glm::radians(12.5f)));
        lightingShader.SetFloat("light.outerCutOff", glm::cos(glm::radians(17.5f)));
        
        lighting.Bind();
        glDrawArrays(GL_TRIANGLES, 0, 36);
        
        lampShader.Use();
        model = glm::mat4(1.0f);
        model = glm::translate(model, lightPos);
        model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
        world = projection * view * model;
        lampShader.SetMat4("world", world);
        lamp1.Bind();
        glDrawArrays(GL_TRIANGLES, 0, 36);
    }
}

void AppDelegate::_LightCasterTest2()
{
    CVertex lighting(&MODEL_CUBE_PTN);
    CVertex lamp1(&MODEL_CUBE);
    CTexture2D diffuseMap(TEXTURE_ROOT"container2.png");
    CTexture2D specularMap(TEXTURE_ROOT"lighting_maps_specular_color.png");
    CShader lightingShader(VERTEXT_ROOT"lightcasterTest1.vs",FRAGMENT_ROOT"lightcasterTest2.fs");
    CShader lampShader(VERTEXT_ROOT"colorTest1-1.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::vec3 lightPos = glm::vec3(-0.2f, -1.0f, -0.3f);
    lightPos = glm::vec3(cos((float)glfwGetTime()+ 1*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 1*3.14*2/3)+ 0.05*(float)glfwGetTime())) , sin((float)glfwGetTime()+ 1*3.14*2/3));
    
    glm::vec3 cubePositions[] = {
        glm::vec3( 0.0f,  0.0f,  0.0f),
        glm::vec3( 2.0f,  5.0f, -15.0f),
        glm::vec3(-1.5f, -2.2f, -2.5f),
        glm::vec3(-3.8f, -2.0f, -12.3f),
        glm::vec3( 2.4f, -0.4f, -3.5f),
        glm::vec3(-1.7f,  3.0f, -7.5f),
        glm::vec3( 1.3f, -2.0f, -2.5f),
        glm::vec3( 1.5f,  2.0f, -2.5f),
        glm::vec3( 1.5f,  0.2f, -1.5f),
        glm::vec3(-1.3f,  1.0f, -1.5f)
    };
    
    glm::mat4 world(1.0f);
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    for(unsigned int i = 0; i < 10; i++)
    {
        lightingShader.Use();
        diffuseMap.Active(GL_TEXTURE0);
        specularMap.Active(GL_TEXTURE1);
        model = glm::mat4(1.0f);
        model = glm::translate(model, cubePositions[i]);
        float angle = 20.0f * i;
        model = glm::rotate(model, (float)glfwGetTime() * glm::radians(angle), glm::vec3(cos((float)glfwGetTime()), 1.0f, sin((float)glfwGetTime())));
        view = m_camera.GetViewMatrix();
        projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
        lightingShader.SetMat4("model", model);
        lightingShader.SetMat4("view", view);
        lightingShader.SetMat4("projection", projection);
        lightingShader.SetVec3("viewPos", m_camera.Position);
        
        //材质
        lightingShader.SetInt("material.diffuse", 0);
        lightingShader.SetInt("material.specular", 1);
        lightingShader.SetFloat("material.shininess", 32.0f);
        
        lightingShader.SetVec4("light.lightVector", lightPos.x, lightPos.y, lightPos.z,0.0f);
        lightingShader.SetVec3("light.ambient", 0.2f, 0.2f, 0.2f);
        lightingShader.SetVec3("light.diffuse", 0.5f, 0.5f, 0.5f);
        lightingShader.SetVec3("light.specular", 1.0f, 1.0f, 1.0f);
        
        lightingShader.SetFloat("light.constant",  1.0f);
        lightingShader.SetFloat("light.linear",    0.09f);
        lightingShader.SetFloat("light.quadratic", 0.032f);
        
        lighting.Bind();
        glDrawArrays(GL_TRIANGLES, 0, 36);
        
        lampShader.Use();
        model = glm::mat4(1.0f);
        model = glm::translate(model, lightPos);
        model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
        world = projection * view * model;
        lampShader.SetMat4("world", world);
        lamp1.Bind();
        glDrawArrays(GL_TRIANGLES, 0, 36);
    }
}

void AppDelegate::_LightCasterTest1()
{
    CVertex lighting(&MODEL_CUBE_PTN);
    CVertex lamp1(&MODEL_CUBE);
    CTexture2D diffuseMap(TEXTURE_ROOT"container2.png");
    CTexture2D specularMap(TEXTURE_ROOT"lighting_maps_specular_color.png");
    CShader lightingShader(VERTEXT_ROOT"lightcasterTest1.vs",FRAGMENT_ROOT"lightcasterTest1.fs");
    CShader lampShader(VERTEXT_ROOT"colorTest1-1.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::vec3 cubePositions[] = {
        glm::vec3( 0.0f,  0.0f,  0.0f),
        glm::vec3( 2.0f,  5.0f, -15.0f),
        glm::vec3(-1.5f, -2.2f, -2.5f),
        glm::vec3(-3.8f, -2.0f, -12.3f),
        glm::vec3( 2.4f, -0.4f, -3.5f),
        glm::vec3(-1.7f,  3.0f, -7.5f),
        glm::vec3( 1.3f, -2.0f, -2.5f),
        glm::vec3( 1.5f,  2.0f, -2.5f),
        glm::vec3( 1.5f,  0.2f, -1.5f),
        glm::vec3(-1.3f,  1.0f, -1.5f)
    };

    glm::mat4 world(1.0f);
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    for(unsigned int i = 0; i < 10; i++)
    {
        lightingShader.Use();
        diffuseMap.Active(GL_TEXTURE0);
        specularMap.Active(GL_TEXTURE1);
        model = glm::mat4(1.0f);
        model = glm::translate(model, cubePositions[i]);
        float angle = 20.0f * i;
        model = glm::rotate(model, (float)glfwGetTime() * glm::radians(angle), glm::vec3(cos((float)glfwGetTime()), 1.0f, sin((float)glfwGetTime())));
        view = m_camera.GetViewMatrix();
        projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
        lightingShader.SetMat4("model", model);
        lightingShader.SetMat4("view", view);
        lightingShader.SetMat4("projection", projection);
        lightingShader.SetVec3("viewPos", m_camera.Position);

        //材质
        lightingShader.SetInt("material.diffuse", 0);
        lightingShader.SetInt("material.specular", 1);
        lightingShader.SetFloat("material.shininess", 32.0f);

        lightingShader.SetVec4("light.lightVector", -0.2f, -1.0f, -0.3f,0.0f);
        lightingShader.SetVec3("light.ambient", 0.2f, 0.2f, 0.2f);
        lightingShader.SetVec3("light.diffuse", 0.5f, 0.5f, 0.5f);
        lightingShader.SetVec3("light.specular", 1.0f, 1.0f, 1.0f);

        lighting.Bind();
        glDrawArrays(GL_TRIANGLES, 0, 36);

        lampShader.Use();
        model = glm::mat4(1.0f);
        model = glm::translate(model, glm::vec3(-0.2f, -1.0f, -0.3f));
        model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
        world = projection * view * model;
        lampShader.SetMat4("world", world);
        lamp1.Bind();
        glDrawArrays(GL_TRIANGLES, 0, 36);
    }
}

void AppDelegate::_LightTextureTest2()
{
    CVertex lighting(&MODEL_CUBE_PTN);
    CVertex lamp1(&MODEL_CUBE);
    CTexture2D diffuseMap(TEXTURE_ROOT"container2.png");
    CTexture2D specularMap(TEXTURE_ROOT"lighting_maps_specular_color.png");
    CShader lightingShader(VERTEXT_ROOT"lighttextureTest1.vs",FRAGMENT_ROOT"lighttextureTest2.fs");
    CShader lampShader(VERTEXT_ROOT"colorTest1-1.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::mat4 world(1.0f);
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    
    glm::vec3 lightPos = glm::vec3(cos((float)glfwGetTime()+ 1*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 1*3.14*2/3)+ 0.05*(float)glfwGetTime())) , sin((float)glfwGetTime()+ 1*3.14*2/3));
    
    lightingShader.Use();
    diffuseMap.Active(GL_TEXTURE0);
    specularMap.Active(GL_TEXTURE1);
    //model = glm::mat4(1.0f);
    model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(cos((float)glfwGetTime()), 1.0f, sin((float)glfwGetTime())));
    view = m_camera.GetViewMatrix();
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    lightingShader.SetMat4("model", model);
    lightingShader.SetMat4("view", view);
    lightingShader.SetMat4("projection", projection);
    lightingShader.SetVec3("lightPos", lightPos);
    lightingShader.SetVec3("viewPos", m_camera.Position);
    
    //材质
    lightingShader.SetInt("material.diffuse", 0);
    lightingShader.SetInt("material.specular", 1);
    lightingShader.SetFloat("material.shininess", 32.0f);
    
    
    lightingShader.SetVec3("light.ambient", 0.5f, 0.5f, 0.5f);
    lightingShader.SetVec3("light.diffuse", 0.5f, 0.5f, 0.5f);
    lightingShader.SetVec3("light.specular", 1.0f, 1.0f, 1.0f);
    
    lighting.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    lampShader.Use();
    model = glm::mat4(1.0f);
    model = glm::translate(model, lightPos);
    model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
    world = projection * view * model;
    lampShader.SetMat4("world", world);
    lamp1.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
}

void AppDelegate::_LightTextureTest1()
{
    CVertex lighting(&MODEL_CUBE_PTN);
    CVertex lamp1(&MODEL_CUBE);
    CTexture2D lightingTexture1(TEXTURE_ROOT"container2.png");
    CShader lightingShader(VERTEXT_ROOT"lighttextureTest1.vs",FRAGMENT_ROOT"lighttextureTest1.fs");
    CShader lampShader(VERTEXT_ROOT"colorTest1-1.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::mat4 world(1.0f);
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    
    glm::vec3 lightPos = glm::vec3(cos((float)glfwGetTime()+ 1*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 1*3.14*2/3)+ 0.05*(float)glfwGetTime())) , sin((float)glfwGetTime()+ 1*3.14*2/3));
    
    lightingShader.Use();
    lightingTexture1.Active();
    //model = glm::mat4(1.0f);
    model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(cos((float)glfwGetTime()), 1.0f, sin((float)glfwGetTime())));
    view = m_camera.GetViewMatrix();
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    lightingShader.SetMat4("model", model);
    lightingShader.SetMat4("view", view);
    lightingShader.SetMat4("projection", projection);
    lightingShader.SetVec3("lightPos", lightPos);
    lightingShader.SetVec3("viewPos", m_camera.Position);
    
    //材质
    lightingShader.SetInt("material.diffuse", 0);
    lightingShader.SetFloat("material.shininess", 32.0f);
    lightingShader.SetVec3("material.specular", 0.5f, 0.5f, 0.5f);
    
    
    lightingShader.SetVec3("light.ambient", 0.5f, 0.5f, 0.5f);
    lightingShader.SetVec3("light.diffuse", 0.5f, 0.5f, 0.5f);
    lightingShader.SetVec3("light.specular", 0.0f, 0.0f, 0.0f); //不应该存在镜面光
    
    lighting.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    lampShader.Use();
    model = glm::mat4(1.0f);
    model = glm::translate(model, lightPos);
    model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
    world = projection * view * model;
    lampShader.SetMat4("world", world);
    lamp1.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
}

void AppDelegate::_MateriaTest2()
{
    CVertex lighting(&MODEL_CUBE_N);
    CVertex lamp1(&MODEL_CUBE);
    CShader lightingShader(VERTEXT_ROOT"lightTest3.vs",FRAGMENT_ROOT"materialTest2.fs");
    CShader lampShader(VERTEXT_ROOT"colorTest1-1.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::mat4 world(1.0f);
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    
    glm::vec3 lightPos = glm::vec3(cos((float)glfwGetTime()+ 1*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 1*3.14*2/3)+ 0.05*(float)glfwGetTime())) , sin((float)glfwGetTime()+ 1*3.14*2/3));
    
    lightingShader.Use();
    //model = glm::mat4(1.0f);
    model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(cos((float)glfwGetTime()), 1.0f, sin((float)glfwGetTime())));
    view = m_camera.GetViewMatrix();
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    lightingShader.SetMat4("model", model);
    lightingShader.SetMat4("view", view);
    lightingShader.SetMat4("projection", projection);
    lightingShader.SetVec3("objectColor", 1.0f, 0.5f, 0.31f);
    lightingShader.SetVec3("lightColor",  1.0f, 1.0f, 1.0f);
    lightingShader.SetVec3("lightPos", lightPos);
    lightingShader.SetVec3("viewPos", m_camera.Position);
    
    //材质
    lightingShader.SetVec3("material.ambient",  1.0f, 0.5f, 0.31f);
    lightingShader.SetVec3("material.diffuse",  1.0f, 0.5f, 0.31f);
    lightingShader.SetVec3("material.specular", 0.5f, 0.5f, 0.5f);
    lightingShader.SetFloat("material.shininess", 32.0f);
    
    //环境光
//    lightingShader.SetVec3("light.ambient",  0.2f, 0.2f, 0.2f);
//    lightingShader.SetVec3("light.diffuse",  0.5f, 0.5f, 0.5f); // 将光照调暗了一些以搭配场景
//    lightingShader.SetVec3("light.specular", 1.0f, 1.0f, 1.0f);
    
    glm::vec3 lightColor;
    lightColor.x = sin(glfwGetTime() * 2.0f);
    lightColor.y = sin(glfwGetTime() * 0.7f);
    lightColor.z = sin(glfwGetTime() * 1.3f);
    
    glm::vec3 diffuseColor = lightColor   * glm::vec3(0.5f); // 降低影响
    glm::vec3 ambientColor = diffuseColor * glm::vec3(0.2f); // 很低的影响
    
    lightingShader.SetVec3("light.ambient", ambientColor);
    lightingShader.SetVec3("light.diffuse", diffuseColor);
    lightingShader.SetVec3("light.specular", 1.0f, 1.0f, 1.0f);
    
    lighting.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    lampShader.Use();
    model = glm::mat4(1.0f);
    model = glm::translate(model, lightPos);
    model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
    world = projection * view * model;
    lampShader.SetMat4("world", world);
    lamp1.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
}

void AppDelegate::_MateriaTest1()
{
    CVertex lighting(&MODEL_CUBE_N);
    CVertex lamp1(&MODEL_CUBE);
    CShader lightingShader(VERTEXT_ROOT"lightTest3.vs",FRAGMENT_ROOT"materialTest1.fs");
    CShader lampShader(VERTEXT_ROOT"colorTest1-1.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::mat4 world(1.0f);
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    
    lightingShader.Use();
    //model = glm::mat4(1.0f);
    model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(cos((float)glfwGetTime()), 1.0f, sin((float)glfwGetTime())));
    view = m_camera.GetViewMatrix();
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    lightingShader.SetMat4("model", model);
    lightingShader.SetMat4("view", view);
    lightingShader.SetMat4("projection", projection);
    lightingShader.SetVec3("objectColor", 1.0f, 0.5f, 0.31f);
    lightingShader.SetVec3("lightColor",  1.0f, 1.0f, 1.0f);
    lightingShader.SetVec3("lightPos", glm::vec3(1.2f, 1.0f, 2.0f));
    lightingShader.SetVec3("viewPos", m_camera.Position);
    
    lightingShader.SetVec3("material.ambient",  1.0f, 0.5f, 0.31f);
    lightingShader.SetVec3("material.diffuse",  1.0f, 0.5f, 0.31f);
    lightingShader.SetVec3("material.specular", 0.5f, 0.5f, 0.5f);
    lightingShader.SetFloat("material.shininess", 32.0f);
    
    lighting.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    lampShader.Use();
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(cos((float)glfwGetTime()+ 1*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 1*3.14*2/3)+ 0.05*(float)glfwGetTime())) , sin((float)glfwGetTime()+ 1*3.14*2/3)));
    model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
    world = projection * view * model;
    lampShader.SetMat4("world", world);
    lamp1.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
}

void AppDelegate::_LightTest3()
{
    CVertex lighting(&MODEL_CUBE_N);
    CVertex lamp1(&MODEL_CUBE);
    CVertex lamp2(&MODEL_CUBE);
    CVertex lamp3(&MODEL_CUBE);
    CShader lightingShader(VERTEXT_ROOT"lightTest3.vs",FRAGMENT_ROOT"lightTest3.fs");
    CShader lampShader(VERTEXT_ROOT"colorTest1-1.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::mat4 world(1.0f);
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    
    lightingShader.Use();
    model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(0.5f, 1.0f, 0.0f));
    view = m_camera.GetViewMatrix();
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    lightingShader.SetMat4("model", model);
    lightingShader.SetMat4("view", view);
    lightingShader.SetMat4("projection", projection);
    lightingShader.SetVec3("objectColor", 1.0f, 0.5f, 0.31f);
    lightingShader.SetVec3("lightColor",  1.0f, 1.0f, 1.0f);
    lightingShader.SetVec3("lightPos", glm::vec3(1.2f, 1.0f, 2.0f));
    lightingShader.SetVec3("viewPos", m_camera.Position);
    lighting.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    lampShader.Use();
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(cos((float)glfwGetTime()+ 1*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 1*3.14*2/3)+ 0.1*(float)glfwGetTime())), sin((float)glfwGetTime()+ 1*3.14*2/3)));
    model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
    world = projection * view * model;
    lampShader.SetMat4("world", world);
    lamp1.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(cos((float)glfwGetTime() + 2*3.14*2/3),  0.2*sin((float)(((float)glfwGetTime() + 2*3.14*2/3)+ 0.1*(float)glfwGetTime())), sin((float)glfwGetTime()+ 2*3.14*2/3)));
    model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
    world = projection * view * model;
    lampShader.SetMat4("world", world);
    lamp2.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(cos((float)glfwGetTime()+ 3*3.14*2/3), 0.2*sin((float)(((float)glfwGetTime() + 3*3.14*2/3)+ 0.1*(float)glfwGetTime())), sin((float)glfwGetTime()+ 3*3.14*2/3)));
    model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
    world = projection * view * model;
    lampShader.SetMat4("world", world);
    lamp3.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
}


void AppDelegate::_LightTest2()
{
    CVertex lighting(&MODEL_CUBE_N);
    CVertex lamp(&MODEL_CUBE);
    CShader lightingShader(VERTEXT_ROOT"lightTest2.vs",FRAGMENT_ROOT"lightTest2.fs");
    CShader lampShader(VERTEXT_ROOT"colorTest1-1.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::mat4 world(1.0f);
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    
    lightingShader.Use();
    model = glm::mat4(1.0f);
    view = m_camera.GetViewMatrix();
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    lightingShader.SetMat4("model", model);
    lightingShader.SetMat4("view", view);
    lightingShader.SetMat4("projection", projection);
    lightingShader.SetVec3("objectColor", 1.0f, 0.5f, 0.31f);
    lightingShader.SetVec3("lightColor",  1.0f, 1.0f, 1.0f);
    lightingShader.SetVec3("lightPos", glm::vec3(1.2f, 1.0f, 2.0f));
    lighting.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    lampShader.Use();
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(1.2f, 1.0f, 2.0f));
    model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
    world = projection * view * model;
    lampShader.SetMat4("world", world);
    lamp.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
}



void AppDelegate::_LightTest1()
{
    CVertex lighting(&MODEL_CUBE);
    CVertex lamp(&MODEL_CUBE);
    CShader lightingShader(VERTEXT_ROOT"colorTest1.vs",FRAGMENT_ROOT"lightTest1.fs");
    CShader lampShader(VERTEXT_ROOT"colorTest1-1.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::mat4 world(1.0f);
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);
    
    lightingShader.Use();
    model = glm::mat4(1.0f);
    view = m_camera.GetViewMatrix();
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    world = projection * view * model;
    lightingShader.SetMat4("world", world);
    lightingShader.SetVec3("objectColor", 1.0f, 0.5f, 0.31f);
    lightingShader.SetVec3("lightColor",  1.0f, 1.0f, 1.0f);
    lighting.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    lampShader.Use();
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(1.2f, 1.0f, 2.0f));
    model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
    world = projection * view * model;
    lampShader.SetMat4("world", world);
    lamp.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
}

void AppDelegate::_ColorTest1()
{
    CVertex lighting(&MODEL_CUBE);
    CVertex lamp(&MODEL_CUBE);
    CShader lightingShader(VERTEXT_ROOT"colorTest1.vs",FRAGMENT_ROOT"colorTest1.fs");
    CShader lampShader(VERTEXT_ROOT"colorTest1-1.vs",FRAGMENT_ROOT"colorTest1-1.fs");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::mat4 world(1.0f);
    glm::mat4 model(1.0f);
    glm::mat4 view(1.0f);
    glm::mat4 projection(1.0f);

    lightingShader.Use();
    model = glm::mat4(1.0f);
    view = m_camera.GetViewMatrix();
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    world = projection * view * model;
    lightingShader.SetMat4("world", world);
    lightingShader.SetVec3("objectColor", 1.0f, 0.5f, 0.31f);
    lightingShader.SetVec3("lightColor",  1.0f, 1.0f, 1.0f);
    lighting.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    lampShader.Use();
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(1.2f, 1.0f, 2.0f));
    model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
    world = projection * view * model;
    lampShader.SetMat4("world", world);
    lamp.Bind();
    glDrawArrays(GL_TRIANGLES, 0, 36);

    
}

void AppDelegate::_OtherCoord()
{
    CVertex vertex(VEROBJ_ROOT"cube.vo");
    CShader shader(VERTEXT_ROOT"coordTest1.vs",FRAGMENT_ROOT"dark2.fs");
    CTexture2D texture1(TEXTURE_ROOT"wall.jpg");
    CTexture2D texture2(TEXTURE_ROOT"awesomeface.png");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    texture1.Active(GL_TEXTURE0);
    texture2.Active(GL_TEXTURE1);
    shader.Use();
    vertex.Bind();             //绑定顶点数组对象
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::mat4 model(1.0f);
    model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));
    glm::mat4 view(1.0f);
    view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));// 注意，我们将矩阵向我们要进行移动场景的反方向移动。
    glm::mat4 projection(1.0f);
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    
    shader.SetMat4("model", model);
    shader.SetMat4("view", view);
    shader.SetMat4("projection", projection);
    
    shader.SetInt("texture1", 0);
    shader.SetInt("texture2", 1);
    
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}

void AppDelegate::_CoordTest3()
{
    float vertices[] = {
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
        0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
        
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
    };
    CVertex buffer(CVertex::FVF_POS|CVertex::FVF_TEX2D,nullptr,vertices,sizeof(vertices));
    CShader shader(VERTEXT_ROOT"coordTest1.vs",FRAGMENT_ROOT"dark2.fs");
    CTexture2D texture1(TEXTURE_ROOT"wall.jpg");
    CTexture2D texture2(TEXTURE_ROOT"awesomeface.png");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    texture1.Active(GL_TEXTURE0);
    texture2.Active(GL_TEXTURE1);
    shader.Use();
    buffer.Bind();             //绑定顶点数组对象
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    glm::vec3 cubePositions[] = {
        glm::vec3( 0.0f,  0.0f,  0.0f),
        glm::vec3( 2.0f,  5.0f, -15.0f),
        glm::vec3(-1.5f, -2.2f, -2.5f),
        glm::vec3(-3.8f, -2.0f, -12.3f),
        glm::vec3( 2.4f, -0.4f, -3.5f),
        glm::vec3(-1.7f,  3.0f, -7.5f),
        glm::vec3( 1.3f, -2.0f, -2.5f),
        glm::vec3( 1.5f,  2.0f, -2.5f),
        glm::vec3( 1.5f,  0.2f, -1.5f),
        glm::vec3(-1.3f,  1.0f, -1.5f)
    };
    for(unsigned int i = 0; i < 10; i++)
    {
        glm::mat4 model(1.0f);
        model = glm::translate(model, cubePositions[i]);
        float angle = 20.0f * i;
        model = glm::rotate(model, (float)glfwGetTime() * glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
        glm::mat4 view(1.0f);
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));// 注意，我们将矩阵向我们要进行移动场景的反方向移动。
        glm::mat4 projection(1.0f);
        projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
        
        shader.SetMat4("model", model);
        shader.SetMat4("view", view);
        shader.SetMat4("projection", projection);
        shader.SetInt("texture1", 0);
        shader.SetInt("texture2", 1);
        
        glDrawArrays(GL_TRIANGLES, 0, 36);
    }
}


void AppDelegate::_CoordTest2()
{
    float vertices[] = {
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
        0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
        
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
    };
    CVertex buffer(CVertex::FVF_POS|CVertex::FVF_TEX2D,nullptr,vertices,sizeof(vertices));
    CShader shader(VERTEXT_ROOT"coordTest1.vs",FRAGMENT_ROOT"dark2.fs");
    CTexture2D texture1(TEXTURE_ROOT"wall.jpg");
    CTexture2D texture2(TEXTURE_ROOT"awesomeface.png");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    texture1.Active(GL_TEXTURE0);
    texture2.Active(GL_TEXTURE1);
    shader.Use();
    buffer.Bind();             //绑定顶点数组对象
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    glm::mat4 model(1.0f);
    model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(0.5f, 1.0f, 0.0f));
    glm::mat4 view(1.0f);
    view = m_camera.GetViewMatrix();
    glm::mat4 projection(1.0f);
    projection = glm::perspective(glm::radians(m_camera.Zoom), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);
    
    shader.SetMat4("model", model);
    shader.SetMat4("view", view);
    shader.SetMat4("projection", projection);
    shader.SetInt("texture1", 0);
    shader.SetInt("texture2", 1);
    
    glDrawArrays(GL_TRIANGLES, 0, 36);
}

void AppDelegate::_CoordTest1()
{
    CVertex buffer([](unsigned int ,unsigned int,unsigned int){
        float vertices[] = {
            //     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -
            0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // 右上
            0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // 右下
            -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // 左下
            -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // 左上
        };
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//将顶点数据写入绑定的顶点缓存对象

        unsigned int indices[] = {
            0, 1, 3, // first triangle
            1, 2, 3  // second triangle
        };
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

        // 位置属性
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(0);
        // 颜色属性
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3* sizeof(float)));
        glEnableVertexAttribArray(1);

        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
        glEnableVertexAttribArray(2);

    });

    CShader shader(VERTEXT_ROOT"coordTest1.vs",FRAGMENT_ROOT"dark2.fs");
    CTexture2D texture1(TEXTURE_ROOT"wall.jpg");
    CTexture2D texture2(TEXTURE_ROOT"awesomeface.png");
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    texture1.Active(GL_TEXTURE0);
    texture2.Active(GL_TEXTURE1);
    shader.Use();
    buffer.Bind();             //绑定顶点数组对象
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    glm::mat4 model(1.0f);
    model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));
    glm::mat4 view(1.0f);
    view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));// 注意，我们将矩阵向我们要进行移动场景的反方向移动。
    glm::mat4 projection(1.0f);
    projection = glm::perspective(glm::radians(45.0f), (float)GLSApplication::GetWidth() / (float)GLSApplication::GetHeight(), 0.1f, 100.0f);

    shader.SetMat4("model", model);
    shader.SetMat4("view", view);
    shader.SetMat4("projection", projection);
    
    shader.SetInt("texture1", 0);
    shader.SetInt("texture2", 1);
    
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

}


